Jitter 教程翻译04 - 创建矩阵
Max/MSP/Jitter 教程 01 - 什么是矩阵?
Max/MSP/Jitter 教程 02 - Jitter 对象的属性
Max/MSP/Jitter 教程 03 - 播放 QuickTime 视频
00 翻译自 Cycling74 的 Max/MSP/Jitter 官方文档:Tutorial 2: Create a Matrix
https://docs.cycling74.com/max7/tutorials/jitterchapter02
什么是矩阵?
本教程讲解处理矩阵数据的方法。可以先回顾一下 Max/MSP/Jitter 教程 01 - 什么是矩阵?
矩阵用虚拟的网格来存储和修改大批的数值数据。数据存储在矩阵中,就可以通过网格位置查找,并指定整个矩阵或部分矩阵来批量修改多个值。
在上一篇教程中,我们使用 jit.window
对象打开一个窗口,并将矩阵的内容显示为彩色像素。
显示的矩阵来自 jit.movie
对象,它用 QuickTime 视频的当前帧连续填充矩阵。jit.window
之所以能显示视频,只不过因为被告知要显示哪些矩阵的内容; 事实上,矩阵中的任何数值都可以显示。本教程通过一个更简单的例子帮助你理解矩阵,它是 Jitter 的核心思想。
以下是本节完整的 patcher 截图
jit.matrix 对象
为单个 8 位值创建 16x12 存储空间
jit.matrix
对象创建矩阵并在内存中声明存储空间,以便我们存储和检索数值,并打印或显示出来。 jit.matrix
的参数包括:
[name](可选,本例中未包含)
[planecount](在矩阵的每个单元格中存储多少个值)
[type](用多少个字节来表示每个数字)
[dim](维度,描述矩阵的大小)
括号 [] 里面应填入实际的赋值。上面的例子创建了 1 个平面(每个矩阵单元包含 1 个数字)、尺寸为 16x12(共 192 个单元格)的 char 型(单字节值)矩阵。由此可以推断出矩阵能够保存 192 个单独的数值,每个值的范围是 0~255(单个字节的范围)。
注意:在 Max 中用 x,y(宽度,高度)格式描述二维矩阵的维数,先给出水平维度的范围,然后是垂直维度。这跟视频和计算机屏幕坐标处理尺寸的方式一致(例如,640x480 视频图像)。即,先说明有多少列(宽),再说明有多少行(高)。需要注意,Jitter 描述行和列,与线性代数中描述矩阵的惯例(先表示行,然后是列)不同。
回到例子中,一个按钮连接到 jit.matrix
的入口。当 Jitter 对象在左入口接收到 bang
消息时会发送矩阵名称,这个按钮会触发 jit.matrix
发送它的矩阵名称(以 jit_matrix
消息的形式)。
jit.print对象
打印 jit.matrix
的内容
在 jit.matrix
下面有一个新的 Jitter 对象:jit.print
。它在入口处接收矩阵名称(jit_matrix
消息)并格式化矩阵的值,以便在 Max Console 中打印。它将格式化的值打印到 Max Console,就像 Max 的 print
对象一样,然后在 jit_matrix
消息中以矩阵名称的形式传递出来。
单击标记为 “output” 的按钮,这会让 jit.matrix
传递矩阵名称给 jit.print
,后者格式化值并在 Max Console 中显示:jit_matrix [somename]
。左边的单词表示这是由 jit.print
对象打印的,这是 jit.matrix
出口的结果。
因为我们没有指定矩阵的名称(没有指定 jit.matrix
的第一个输入参数),所以 jit.matrix
自己会生成唯一名称(类似 “u330000007”)。这里我们并不关心名称是什么,但它能够告诉 jit.print
对象要显示哪个矩阵的数据。
上图显示了来自 jit.print
矩阵中的所有值,按 16 列和 12 行整齐排列。它们现在都是 0,因为我们还没有在矩阵中填充任何内容。
在矩阵中设置和查询值
在上一章中,我们知道如何使用 QuickTime 视频中的彩色数据帧自动填充整个矩阵。还可以将数值放置在矩阵的特定单元格中,并从特定位置检索。
在下面的例子中,jit.matrix
上方有一些消息框,可以设置和获取矩阵中的值。
使用 setcell
消息可以在特定的矩阵位置中存储值。语法是: setcell [cell coordinates] val [value(s)]
。
例如, jit.matrix
消息 setcell 0 0 val 127
会将矩阵的第一个单元格(即左上角的单元格)的值设置为 127。每个维度中对单元格坐标的编号从 0 开始,最大值比维度小 1。在此矩阵中,x 维度中的位置编号为 0~15,y 维度中的位置编号为 0~11。因此右下角的单元格坐标是 15 11.
pack 0 0 0
对象组合多个数字提供给setcell
消息发送给 jit.matrix
。首先设置想要存储值的 x 和 y 位置,然后指定要存储在那里的值。当 x 和 y 位置为 0 0 时,用标有“value” 的数字框发送 127 到 pack 0 0 0
的左侧入口。这将触发消息 setcell 0 0 val 127
发送给 jit.matrix
。
消息 setcell 0 0 val 127
设置单元位置 0,0 的值为 127
(如果矩阵中有多个平面,可以在单元格的特定/所有平面中设置值)
为了演示之前提过的单元格位置编号,现在尝试将消息 setcell 15 11 val 255
发送到 jit.matrix
。在 “X position” 下面的数字框输入 15,在 “Y position” 下面的数字框输入 11 ,在 “value” 下面的数字框输入 255。然后点击 “output” 按钮查看矩阵的变化。jit.print
在 Max 控制台中打印出整个矩阵。请注意,单元格位置 0,0 和 15,11 中的值已变为 127 和 255。
消息 setcell 15 11 val 255
将单元格位置 15,11 的值设置为 255
在 Patch 窗口中,你可能已经注意到黑色矩形区域的变化。它的左上角和右下角已经改变了。
jit.pwindow
对象显示的数值为颜色(或灰度值)
该区域是一个名为 jit.pwindow
的用户界面对象。在添加对象面板中可以找到它:
对象选项板中的 jit.pwindow
图标
在添加对象面板中单击或将其拖动到 patch 窗口时,它会创建一个小的矩形对象(可以拖动对象右下角调整尺寸)。它在功能上与 jit.window
非常相似,区别是它在 Patch 窗口中显示矩阵数据,而不是在一个单独的窗口。
于是我们看到数值显示为颜色(char 数值范围是 0~255)。矩阵中只有一个平面,所以是单色(即灰度)。0 表示黑色,其他值是某种灰度,最大值255 是白色。因此,单元格 15,11 的 255 值显示为白色,0,0 的 127 值显示为黑色和白色之间的 50% 灰色。
你可能会觉得这样填充矩阵相当繁琐。没错。所以 Max 允许我们编写程序来自动填充。
以算法方式填充矩阵
双击 patcher fillmatrix
对象打开子 patch。它将不同的数字传入数学表达式,生成 192 个不同的值到矩阵中的每个单元。
通过算法生成值来填充矩阵的单元格
当 uzi 12
对象收到 bang
(点击主 Patch 窗口中标记为 “fill” 的按钮)时,它会快速从右侧出口进行 1 到 12 计数,并向左侧出口发送每个计数的 bang。
那些 bang 触发了uzi 16
对象,因此它每次都会发出 1~16 的数字。然后把这些数字减去 1,这样值的范围就限定在 0~11 和 0~15,输出的结果作为矩阵中的 y 和 x 位置。对于 12 个 y 位置中的每一个,uzi 16
对象指定所有 x 位置,然后在数学表达式(expr)中使用这些数字来计算要存储在该位置的值。这些数字从 outlet 发送给主 patch 创建定义好的 setcell
消息,就像我们之前手动做的那样。
这里不需要关注具体的数学表达式。它可以生成任何公式。刚才我们用一个公式在每列中产生亮度的正弦梯度,这将让列的整体亮度从左向右增加(即随 x 增加)。
关闭 patcher fillmatrix
,然后单击标记为 “fill” 的按钮。矩阵在 Max 的 scheduler 的每个时钟节拍中填充值(由子 patch 中的 uzi 对象生成)。现在单击标有 “output” 的按钮查看矩阵的内容。数值将打印在 Max Console 中,并显示在 jit.pwindow
中。
即使对于像 16x12 这样的小型矩阵,仅仅查看 Max Console 中的数字打印输出,我们很难看到数值数据的趋势。而 jit.pwindow
中的显示能够清楚而直观地展示值在矩阵中的变化情况。这是数据可视化的好处。
你可以想象在 Max 中以算法方式填充矩阵的其他方法,我们将在后面的教程中演示。
jit.matrix 可以响应的其他消息
jit.matrix
还可以接收许多其他消息。例如可以使用相同的值填充所有 jit.matrix
。发送给jit.matrix
的 clear
消息将所有值设置为 0,setall
消息(setall 后跟一个值)将矩阵中的所有单元设置为同一个值。
查询矩阵位置 8,6 处的值; 报告单元格 8 6 val [value(s)]
还有 getcell
消息。单词 getcell
后跟矩阵中的位置(x和y)会让 jit.matrix
将单元格坐标和该位置的值发送到右侧出口。
在 getcell $1 $2
消息框上方的数字框中输入 y 值,然后输入 x 值,并观察 Max Console 中打印的内容。请注意,该矩阵位置的值在 jit.matrix
的右侧出口输出。
在后面的教程中,你将看到从矩阵中检索值的各种方法。
小结
jit.matrix
对象可以为任何尺寸、平面数和数据类型的矩阵数据创建存储空间。该矩阵可以填充另一个 Jitter 对象(例如 jit.movie
)的数据,或者用 setall [value]
之类的消息来设置所有单元格中的值,或者 setcell [position] val [value(s)]
来设置指定单元。可以使用 patch 中其他位置的算法,根据公式或一组规则来填充矩阵。
要获取特定单元格中的数据,可以使用 getcell [position]
消息。要查看在 Max Console 中打印的所有数值数据,请使用 jit.print
对象格式化矩阵数据并打印。要查看显示为颜色的矩阵数据,请使用 jit.pwindow
对象。这类似于上一篇教程中演示的 jit.window
对象。
在本教程中,我们查看了手动生成的数据,而不是上一篇中的视频数据。两种情况下的存储原理是相同的。无论矩阵是存储来自数字视频帧的每个像素的颜色信息,还是表示颜色的数字,它们都存储在二维矩阵中,并且通过 jit.window
或 jit.pwindow
显示。
友情提示:独自折腾 Max 易患上癔症……不妨入群互助
👇👇👇
更多 Max/MSP 应用,请翻阅 MakeNoise 系列
MakeNoise01 - 声音是什么?
MakeNoise02 - 频率和音高
MakeNoise03 - 振幅/响度/音量/增益 大乱斗
MakeNoise04 - 波形和相位
MakeNoise05 - Envelope 包络(ADSR)
MakeNoise06 - 音色和均衡器(EQ)
MakeNoise07 - 音频的「分辨率」
MakeNoise08 - 振荡器和滤波器
MakeNoise09 - 压缩 Compression
MakeNoise10 - 延时和混响